use crate::{
    config::{channel_config::ChannelConfig, native_version_config::NativeVersionConfig},
    core::entity::native_version_pair::NativeVersionPair,
    router::channel_setting_router::rsp::GetChannelInfoResponse,
};
use directories::{ProjectDirs, UserDirs};
use lazy_static::lazy_static;
use share::core::channel::Channel;

pub struct Util {}

const QUALIFIER: &str = "com";
const ORGANIZATION: &str = "beargod";
const APP_NAME: &str = "ctapi";

lazy_static! {
    static ref APP_DIRS: ProjectDirs =
        ProjectDirs::from(QUALIFIER, ORGANIZATION, APP_NAME).expect("Can not get app directories");
    static ref USER_DIRS: UserDirs = UserDirs::new().expect("Can not get user directories");
}

impl Util {
    pub fn app_name() -> String {
        APP_NAME.to_string()
    }
    pub fn app_dirs() -> &'static ProjectDirs {
        &(APP_DIRS)
    }

    pub fn user_dirs() -> &'static UserDirs {
        &(USER_DIRS)
    }

    pub async fn get_channel_setting(c: Channel) -> ChannelConfig {
        let api_domain = c.get_api_domain();
        let url = format!("https://{}/channel_setting/info/{}", api_domain, c);

        let json = reqwest::get(url.clone())
            .await
            .expect(&format!("Failed to get, url: {}", url.clone()))
            .text()
            .await
            .expect(&format!(
                "Failed to get content from response, url: {}",
                url
            ));

        let response: GetChannelInfoResponse = serde_json::from_str(&json)
            .expect(&format!("Failed to deserialize, content: {}", json));

        let native_version =
            NativeVersionPair::new(response.min_native_version, response.latest_native_version)
                .map_err(|e| e.to_string())
                .unwrap();

        let hot_update_settings = response
            .hot_update_settings
            .into_iter()
            .map(|(nv, info)| {
                (
                    nv,
                    NativeVersionConfig {
                        resource_version: info.resource_version,
                        resource_url: info.resource_url,
                    },
                )
            })
            .collect();

        ChannelConfig {
            channel: c,
            native_version,
            jump_url: response.jump_url,
            hot_update_settings,
        }
    }
}
